home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 22 / AACD 22.iso / AACD / Online / Apache / lib / php / DB / mysql.php < prev    next >
Encoding:
PHP Script  |  2001-03-06  |  10.8 KB  |  445 lines

  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | PHP version 4.0                                                      |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group                   |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license,      |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Stig Bakken <ssb@fast.no>                                   |
  17. // |                                                                      |
  18. // +----------------------------------------------------------------------+
  19. //
  20. // Database independent query interface definition for PHP's MySQL
  21. // extension.
  22. //
  23.  
  24. //
  25. // XXX legend:
  26. //
  27. // XXX ERRORMSG: The error message from the mysql function should
  28. //                 be registered here.
  29. //
  30.  
  31. require_once 'DB/common.php';
  32.  
  33. class DB_mysql extends DB_common {
  34.     // {{{ properties
  35.  
  36.     var $connection;
  37.     var $phptype, $dbsyntax;
  38.     var $prepare_tokens = array();
  39.     var $prepare_types = array();
  40.  
  41.     // }}}
  42.  
  43.     // {{{ constructor
  44.  
  45.     /**
  46.      * DB_mysql constructor.
  47.      *
  48.      * @access public
  49.      */
  50.     function DB_mysql() {
  51.         $this->phptype = 'mysql';
  52.         $this->dbsyntax = 'mysql';
  53.         $this->features = array(
  54.             'prepare' => false,
  55.             'pconnect' => true,
  56.             'transactions' => false
  57.         );
  58.         $this->errorcode_map = array(
  59.             1004 => DB_ERROR_CANNOT_CREATE,
  60.             1005 => DB_ERROR_CANNOT_CREATE,
  61.             1006 => DB_ERROR_CANNOT_CREATE,
  62.             1007 => DB_ERROR_ALREADY_EXISTS,
  63.             1008 => DB_ERROR_CANNOT_DROP,
  64.             1046 => DB_ERROR_NODBSELECTED,
  65.             1146 => DB_ERROR_NOSUCHTABLE,
  66.             1064 => DB_ERROR_SYNTAX,
  67.             1054 => DB_ERROR_NOSUCHFIELD,
  68.             1062 => DB_ERROR_ALREADY_EXISTS,
  69.             1051 => DB_ERROR_NOSUCHTABLE,
  70.             1100 => DB_ERROR_NOT_LOCKED,
  71.             1136 => DB_ERROR_VALUE_COUNT_ON_ROW,
  72.         );
  73.     }
  74.  
  75.     // }}}
  76.  
  77.     // {{{ connect()
  78.  
  79.     /**
  80.      * Connect to a database and log in as the specified user.
  81.      *
  82.      * @param $dsn the data source name (see DB::parseDSN for syntax)
  83.      * @param $persistent (optional) whether the connection should
  84.      *        be persistent
  85.      * @access public
  86.      * @return int DB_OK on success, a DB error on failure
  87.      */
  88.     function connect(&$dsn, $persistent = false) {
  89.         if (is_array($dsn)) {
  90.             $dsninfo = &$dsn;
  91.         } else {
  92.             $dsninfo = DB::parseDSN($dsn);
  93.         }
  94.         if (!$dsninfo || !$dsninfo['phptype']) {
  95.             return $this->raiseError(); // XXX ERRORMSG
  96.         }
  97.         $dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost';
  98.         $user = $dsninfo['username'];
  99.         $pw = $dsninfo['password'];
  100.         $connect_function = $persistent ? 'mysql_pconnect' : 'mysql_connect';
  101.         if ($dbhost && $user && $pw) {
  102.             $conn = $connect_function($dbhost, $user, $pw);
  103.         } elseif ($dbhost && $user) {
  104.             $conn = $connect_function($dbhost, $user);
  105.         } elseif ($dbhost) {
  106.             $conn = $connect_function($dbhost);
  107.         } else {
  108.             $conn = false;
  109.         }
  110.         if ($conn == false) {
  111.             return $this->raiseError(); // XXX ERRORMSG
  112.         }
  113.         if ($dsninfo['database']) {
  114.             if (!mysql_select_db($dsninfo['database'], $conn)) {
  115.                 return $this->raiseError(); // XXX ERRORMSG
  116.             }
  117.         }
  118.         $this->connection = $conn;
  119.         return DB_OK;
  120.     }
  121.  
  122.     // }}}
  123.     // {{{ disconnect()
  124.  
  125.     /**
  126.      * Log out and disconnect from the database.
  127.      *
  128.      * @access public
  129.      *
  130.      * @return bool TRUE on success, FALSE if not connected.
  131.      */
  132.     function disconnect() {
  133.         return mysql_close($this->connection); // XXX ERRORMSG
  134.     }
  135.  
  136.     // }}}
  137.     // {{{ query()
  138.  
  139.  
  140.     /**
  141.      * Send a query to MySQL and return the results as a DB_result object.
  142.      *
  143.      * @param $query the SQL query
  144.      *
  145.      * @access public
  146.      *
  147.      * @return object a DB_result object on success, a DB error
  148.      * on failure
  149.      */
  150.     function &query($query) {
  151.         $this->last_query = $query;
  152.         $result = @mysql_query($query, $this->connection);
  153.         if (!$result) {
  154.             return $this->raiseError($this->errorCode(mysql_errno($this->connection)));
  155.         }
  156.         // Determine which queries that should return data, and which
  157.         // should return an error code only.
  158.         if (preg_match('/(SELECT|SHOW)/i', $query)) {
  159.             $resultObj = new DB_result($this, $result);
  160.             return $resultObj;
  161.         } else {
  162.             return DB_OK;
  163.         }
  164.     }
  165.  
  166.     // }}}
  167.     // {{{ simpleQuery()
  168.  
  169.     /**
  170.      * Send a query to MySQL and return the results as a MySQL resource
  171.      * identifier.
  172.      *
  173.      * @param $query the SQL query
  174.      *
  175.      * @access public
  176.      *
  177.      * @return int returns a valid MySQL result for successful SELECT
  178.      * queries, DB_OK for other successful queries.  A DB error is
  179.      * returned on failure.
  180.      */
  181.     function simpleQuery($query) {
  182.         $this->last_query = $query;
  183.         $result = mysql_query($query, $this->connection);
  184.         if (!$result) {
  185.             return $this->raiseError($this->errorCode(mysql_errno($this->connection)));
  186.         }
  187.         // Determine which queries that should return data, and which
  188.         // should return an error code only.
  189.         if (preg_match('/(SELECT|SHOW)/i', $query)) {
  190.             return $result;
  191.         } else {
  192.             return DB_OK;
  193.         }
  194.     }
  195.  
  196.     // }}}
  197.     // {{{ fetchRow()
  198.  
  199.     /**
  200.      * Fetch a row and return as array.
  201.      *
  202.      * @param $result MySQL result identifier
  203.      * @param $fetchmode how the resulting array should be indexed
  204.      *
  205.      * @access public
  206.      *
  207.      * @return mixed an array on success, a DB error on failure, NULL
  208.      *               if there is no more data
  209.      */
  210.     function &fetchRow($result, $fetchmode = DB_FETCHMODE_DEFAULT) {
  211.         if ($fetchmode == DB_FETCHMODE_DEFAULT) {
  212.             $fetchmode = $this->fetchmode;
  213.         }
  214.         if ($fetchmode & DB_FETCHMODE_ASSOC) {
  215.             $row = mysql_fetch_array($result, MYSQL_ASSOC);
  216.         } else {
  217.             $row = mysql_fetch_row($result);
  218.         }
  219.         if (!$row) {
  220.             $errno = mysql_errno($this->connection);
  221.             if (!$errno) {
  222.                 return NULL;
  223.             }
  224.             return $this->raiseError($this->errorCode($errno));
  225.         }
  226.         return $row;
  227.     }
  228.  
  229.     // }}}
  230.     // {{{ fetchInto()
  231.  
  232.     /**
  233.      * Fetch a row and insert the data into an existing array.
  234.      *
  235.      * @param $result MySQL result identifier
  236.      * @param $arr (reference) array where data from the row is stored
  237.      * @param $fetchmode how the array data should be indexed
  238.      *
  239.      * @access public
  240.      *
  241.      * @return int DB_OK on success, a DB error on failure
  242.      */
  243.     function fetchInto($result, &$arr, $fetchmode = DB_FETCHMODE_DEFAULT) {
  244.         if ($fetchmode == DB_FETCHMODE_DEFAULT) {
  245.             $fetchmode = $this->fetchmode;
  246.         }
  247.         if ($fetchmode & DB_FETCHMODE_ASSOC) {
  248.             $arr = mysql_fetch_array($result, MYSQL_ASSOC);
  249.         } else {
  250.             $arr = mysql_fetch_row($result);
  251.         }
  252.         if (!$arr) {
  253.             $errno = mysql_errno($this->connection);
  254.             if (!$errno) {
  255.                 return NULL;
  256.             }
  257.             return $this->raiseError($this->errorCode($errno));
  258.         }
  259.         return DB_OK;
  260.     }
  261.  
  262.     // }}}
  263.     // {{{ freeResult()
  264.  
  265.     /**
  266.      * Free the internal resources associated with $result.
  267.      *
  268.      * @param $result MySQL result identifier or DB statement identifier
  269.      *
  270.      * @access public
  271.      *
  272.      * @return bool TRUE on success, FALSE if $result is invalid
  273.      */
  274.     function freeResult($result) {
  275.         if (is_resource($result)) {
  276.             return mysql_free_result($result);
  277.         }
  278.         if (!isset($this->prepare_tokens[$result])) {
  279.             return false;
  280.         }
  281.         unset($this->prepare_tokens[$result]);
  282.         unset($this->prepare_types[$result]);
  283.         return true; 
  284.     }
  285.  
  286.     // }}}
  287.     // {{{ numCols()
  288.  
  289.     /**
  290.      * Get the number of columns in a result set.
  291.      *
  292.      * @param $result MySQL result identifier
  293.      *
  294.      * @access public
  295.      *
  296.      * @return int the number of columns per row in $result
  297.      */
  298.     function numCols($result) {
  299.         $cols = mysql_num_fields($result);
  300.         if (!$cols) {
  301.             return $this->raiseError($this->errorCode(mysql_errno($this->connection)));
  302.         }
  303.         return $cols;
  304.     }
  305.  
  306.     // }}}
  307.     // {{{ errorNative()
  308.  
  309.     /**
  310.      * Get the native error code of the last error (if any) that
  311.      * occured on the current connection.
  312.      *
  313.      * @access public
  314.      *
  315.      * @return int native MySQL error code
  316.      */
  317.     function errorNative() {
  318.         return mysql_errno($this->connection);
  319.     }
  320.  
  321.     // }}}
  322.     // {{{ prepare()
  323.  
  324.     /**
  325.      * Prepares a query for multiple execution with execute().  With
  326.      * MySQL, this is emulated.
  327.      *
  328.      * @param $query the SQL query to prepare for execution.  The
  329.      * characters "?" and "&" have special meanings. "?" is a scalar
  330.      * placeholder, the value provided for it when execute()ing is
  331.      * inserted as-is.  "&" is an opaque placeholder, the value
  332.      * provided on execute() is a file name, and the contents of that
  333.      * file will be used in the query.
  334.      *
  335.      * @access public
  336.      *
  337.      * @return int identifier for this prepared query
  338.      */
  339.     function prepare($query) {
  340.         $tokens = split('[\&\?]', $query);
  341.         $token = 0;
  342.         $types = array();
  343.         for ($i = 0; $i < strlen($query); $i++) {
  344.             switch ($query[$i]) {
  345.                 case '?':
  346.                     $types[$token++] = DB_PARAM_SCALAR;
  347.                     break;
  348.                 case '&':
  349.                     $types[$token++] = DB_PARAM_OPAQUE;
  350.                     break;
  351.             }
  352.         }
  353.         $this->prepare_tokens[] = &$tokens;
  354.         end($this->prepare_tokens);
  355.         $k = key($this->prepare_tokens);
  356.         $this->prepare_types[$k] = $types;
  357.         return $k;
  358.     }
  359.  
  360.     // }}}
  361.     // {{{ execute()
  362.  
  363.     /**
  364.      * Executes a prepared query and substitutes placeholders with
  365.      * provided values.
  366.      *
  367.      * @return int returns a MySQL result resource for successful
  368.      * SELECT queries, DB_OK for other successful queries.  A DB error
  369.      * is returned on failure.
  370.      *
  371.      * @see DB_mysql::prepare
  372.      */
  373.     function execute($stmt, $data = false) {
  374.         $realquery = $this->execute_emulate_query($stmt, $data);
  375.         $this->last_query = $realquery;
  376.         $result = mysql_query($realquery, $this->connection);
  377.         if (!$result) {
  378.             return $this->raiseError($this->errorCode(mysql_errno($this->connection)));
  379.         }
  380.         if (preg_match('/(SELECT|SHOW)/i', $realquery)) {
  381.             return $result;
  382.         } else {
  383.             return DB_OK;
  384.         }
  385.     }
  386.  
  387.     // }}}
  388.     // {{{ autoCommit()
  389.  
  390.     /**
  391.      * Enable/disable automatic commits [not supported by MySQL]
  392.      *
  393.      * @access public
  394.      *
  395.      * @return object DB error code (not capable)
  396.      */
  397.     function autoCommit($onoff = false) {
  398.         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  399.     }
  400.  
  401.     // }}}
  402.     // {{{ commit()
  403.  
  404.     /**
  405.      * Commit transactions on the current connection [not supported by MySQL]
  406.      *
  407.      * @access public
  408.      *
  409.      * @return object DB error code (not capable)
  410.      */
  411.     function commit() {
  412.         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  413.     }
  414.  
  415.     // }}}
  416.     // {{{ rollback()
  417.  
  418.     /**
  419.      * Roll back all uncommitted transactions on the current connection.
  420.      * [not supported by MySQL]
  421.      *
  422.      * @access public
  423.      *
  424.      * @return object DB error code (not capable)
  425.      */
  426.     function rollback() {
  427.         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  428.     }
  429.  
  430.     // }}}
  431.  
  432.     // TODO/wishlist:
  433.     // simpleFetch
  434.     // simpleGet
  435.     // affectedRows
  436.     // longReadlen
  437.     // binmode
  438. }
  439.  
  440. // Local variables:
  441. // tab-width: 4
  442. // c-basic-offset: 4
  443. // End:
  444. ?>
  445.